package com.liuym.admin.interceptor;

import com.alibaba.fastjson.JSON;
import com.liuym.admin.common.LogAndExceptionCommon;
import com.liuym.admin.repository.model.vo.AdminVO;
import com.liuym.common.annotation.AdminLogin;
import com.liuym.common.constants.Constants;
import com.liuym.common.constants.RedisConstants;
import com.liuym.common.constants.ResponseCodeConstants;
import com.liuym.common.redis.RedisTemplateManager;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 学生登录验证拦截器，在Controller类上或者方法上标注@StudentLogin，在方法参数中可以注入当前登陆用户@WStudentLoginUser StudentLoginUserBO user
 *
 * @author liuym
 * @date 2019/1/21 20:22
 */
@Configuration
public class AdminLoginInterceptor implements WebMvcConfigurer {
    private static final Logger log = LoggerFactory.getLogger(AdminLoginInterceptor.class);

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        InterceptorRegistration registration = registry.addInterceptor(new HandlerInterceptorAdapter() {
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                //log.info("【接收请求】servletPath={}, parameterMap={}", request.getServletPath(), request.getParameterMap());
                // 检查该拦截器是否生效
                if (handler instanceof HandlerMethod) {
                    HandlerMethod handlerMethod = (HandlerMethod) handler;
                    // 获取方法上的注解
                    AdminLogin login = handlerMethod.getMethod().getAnnotation(AdminLogin.class);
                    // 如果方法上的注解为空，则获取类的注解
                    if (null == login) {
                        login = handlerMethod.getMethod().getDeclaringClass().getAnnotation(AdminLogin.class);
                    }

                    // 如果标记了注解，则判断权限
                    if (null == login) {
                        return true;
                    }
                } else {
                    return true;
                }

                //根据token从redis中获取登录用户信息
                String token = request.getParameter("token");
                if (StringUtils.isBlank(token)) {
                    log.error("【管理员登录验证】失败，token为空");
                    LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                            ResponseCodeConstants.NOT_LOGIN_CODE,
                            ResponseCodeConstants.NOT_LOGIN_MSG,
                            "");
                }
                RedisTemplateManager redisTemplateManager = new RedisTemplateManager(redisTemplate);
                String userStr = redisTemplateManager.getValue(RedisConstants.ADMIN_LOGIN_USER_PREFIX + token);

                if (StringUtils.isBlank(userStr)) {
                    log.error("【管理员登录验证】失败，redis中的缓存为空：token={}, userStr={}", token, userStr);
                    LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                            ResponseCodeConstants.NOT_LOGIN_CODE,
                            ResponseCodeConstants.NOT_LOGIN_MSG,
                            "");
                }
                AdminVO loginUser = JSON.parseObject(userStr, AdminVO.class);
                redisTemplateManager.setKey(RedisConstants.ADMIN_LOGIN_USER_PREFIX + token, userStr, RedisConstants.TOKEN_EXPIRE_TIME);
                request.setAttribute(Constants.ADMIN_LOGIN_USER, loginUser);
                return true;
            }
        });
        // 优先执行
        registration.order(-1);
    }
}